package com.yx.frame.builder.code;

import java.io.OutputStreamWriter;
import java.util.List;
import com.yx.frame.builder.validate.ServiceBuilderConfigManager;
import com.yx.frame.service.Action;

public class ActionCodeBuilder {

	List<Action> actions = null;
	OutputStreamWriter writer = null;
	boolean isJDK18=true;
	boolean isJety=true;
	long timeDifference=-1;

	public ActionCodeBuilder(List<Action> actions, OutputStreamWriter writer,boolean isJDK18,boolean isJety,long timeDifference) {
		this.actions = actions;
		this.writer = writer;
		this.isJDK18=isJDK18;
		this.isJety=isJety;
		this.timeDifference=timeDifference;
	}

	public void builder() throws Exception {
		writer.write(getStarterHead().toString());
		writer.flush();
		int actionsSize = actions.size();
		for (int i = 0; i < actionsSize; i++) {
			StringBuffer aCode = getActionCode(actions.get(i));
			writer.write(aCode.toString());
			writer.flush();
		}
		writer.write(getStarterEnd().toString());
		writer.flush();
	}

	private StringBuffer getStarterHead() {
		StringBuffer code = new StringBuffer();
		code.append("package builder;\r\n");
		code.append("\r\n");
		code.append("import java.util.ArrayList;\r\n");
		code.append("import java.util.List;\r\n");
		code.append("import org.json.JSONObject;\r\n");
		code.append("import com.yx.frame.service.Action;\r\n");
		code.append("import com.yx.frame.service.ActionManager;\r\n");
		code.append("import com.yx.frame.service.ActionMethod;\r\n");
		code.append("import com.yx.frame.authority.User;\r\n");
		code.append("import com.yx.frame.service.ServiceResult;\r\n");
		code.append("import com.yx.frame.jdbc.pool.JdbcConfig;\r\n");		
		code.append("import com.yx.frame.service.Service;\r\n");
		code.append("import com.yx.frame.server.Application;\r\n");
		code.append("\r\n");
		code.append("public final class Starter {\r\n");
		code.append("	public Starter(int port,List<JdbcConfig> jdbcConfig,int logLevel,boolean startJety,int minThreadPoolSize,int maxThreadPoolSize,int minAsyncThreadPoolSize,int maxAsyncThreadPoolSize,int maxUploadFileSize){\r\n");
		code.append("		Action[] actions=new Action[" + actions.size() + "];\r\n");
		return code;
	}
	private StringBuffer getStarterEnd() {
		StringBuffer code = new StringBuffer();
		if(isJDK18){
			code.append("		Application.startAppServer(\"builder.LocalController\",jdbcConfig,actions,logLevel,startJety,true,port,minThreadPoolSize,maxThreadPoolSize,minAsyncThreadPoolSize,maxAsyncThreadPoolSize,maxUploadFileSize,"+timeDifference+");\r\n");
		}else{
			code.append("		Application.startAppServer(\"builder.LocalController\",jdbcConfig,actions,logLevel,startJety,false,port,minThreadPoolSize,maxThreadPoolSize,minAsyncThreadPoolSize,maxAsyncThreadPoolSize,maxUploadFileSize,"+timeDifference+");\r\n");	
		}
		code.append("	}\r\n");
		code.append("	public static void main(String[] args) {\r\n");
		code.append("		int port=Application.getParmInt(args, \"Port\")>=0?Application.getParmInt(args, \"Port\"):"+ServiceBuilderConfigManager.getInstance().getServerPort()+";\r\n");
		code.append("		int logLevel=Application.getParmInt(args, \"LogLevel\")>=0?Application.getParmInt(args, \"LogLevel\"):3;\r\n");
		code.append("		int minThreadPoolSize=Application.getParmInt(args, \"MinThreadPool\")>0?Application.getParmInt(args, \"MinThreadPool\"):"+ServiceBuilderConfigManager.getInstance().getMinThreadPoolSize()+";\r\n");
		code.append("		int maxThreadPoolSize=Application.getParmInt(args, \"MaxThreadPool\")>0?Application.getParmInt(args, \"MaxThreadPool\"):"+ServiceBuilderConfigManager.getInstance().getMaxThreadPoolSize()+";\r\n");
		code.append("		int minAsyncThreadPoolSize=Application.getParmInt(args, \"MinAsyncThreadPool\")>0?Application.getParmInt(args, \"MinAsyncThreadPool\"):"+ServiceBuilderConfigManager.getInstance().getMinAsyncThreadPoolSize()+";\r\n");
		code.append("		int maxAsyncThreadPoolSize=Application.getParmInt(args, \"MaxAsyncThreadPool\")>0?Application.getParmInt(args, \"MaxAsyncThreadPool\"):"+ServiceBuilderConfigManager.getInstance().getMaxAsyncThreadPoolSize()+";\r\n");
		code.append("		int maxUploadFileSize=Application.getParmInt(args, \"UploadFile\")>0?Application.getParmInt(args, \"UploadFile\"):"+ServiceBuilderConfigManager.getInstance().getMaxUploadFileSzie()+";\r\n");
		code.append("		int minJdbcPoolSize=Application.getParmInt(args, \"MinJdbcPool\");\r\n");
		code.append("		int maxJdbcPoolSize=Application.getParmInt(args, \"MaxJdbcPool\");\r\n");
		code.append("		List<JdbcConfig> jdbcConfig=new ArrayList<JdbcConfig>();\r\n");
		String[] dataSourceValues = ServiceBuilderConfigManager.getInstance().getDataSourceValues();
		if (dataSourceValues != null && dataSourceValues.length > 0) {
			for (int i = 0; i < dataSourceValues.length; i++) {
				String[] itemData = dataSourceValues[i].split("\\:");
				String isDefault="false";
				if("Y".equals(itemData[1])){
					isDefault="true";
				}
				String isOracle="false";
				if("Y".equals(itemData[2])){
					isOracle="true";
				}				
				code.append("		jdbcConfig.add(new JdbcConfig(\""+itemData[0]+"\", "+isDefault+", "+isOracle+", \""+itemData[3]+"\", "+itemData[4]+", \""+itemData[5]+"\", \""+itemData[6]+"\", \""+itemData[7]+"\", minJdbcPoolSize>0?minJdbcPoolSize:"+itemData[8]+", maxJdbcPoolSize>0?maxJdbcPoolSize:"+itemData[9]+"));\r\n");
			}
		}
		if(isJety){
			code.append("		Starter start=new Starter(port,jdbcConfig,logLevel,true,minThreadPoolSize,maxThreadPoolSize,minAsyncThreadPoolSize,maxAsyncThreadPoolSize,maxUploadFileSize);\r\n");
		}else{
			code.append("		Starter start=new Starter(port,jdbcConfig,logLevel,false,minThreadPoolSize,maxThreadPoolSize,minAsyncThreadPoolSize,maxAsyncThreadPoolSize,maxUploadFileSize);\r\n");
		}
		code.append("	}\r\n");
		code.append("}\r\n");
		return code;
	}

	private StringBuffer getActionCode(Action action) {
		StringBuffer code = new StringBuffer();
		code.append("		actions[" + action.getId() + "]=new Action("
				+ action.getId() + ",\"" + action.getName() + "\",\""
				+ action.getService() + "\",\"" + action.getMethod() + "\",\""
				+ action.getComment() + "\");\r\n");
		if ("empty".equals(action.getService()))
			return code;
		code.append("		actions[" + action.getId()
				+ "].setActionMethod(new ActionMethod(){\r\n");
		code.append("			public ServiceResult doAction(User user, JSONObject obj) throws Exception{\r\n");
		code.append("				return " + action.getService() + "."
				+ action.getMethod() + "(user,obj);\r\n");
		code.append("			}\r\n");
		code.append("		});\r\n");
		return code;
	}

}
